home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / lib / yotpin / src / spline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-28  |  3.4 KB  |  193 lines

  1. /*
  2. *    Yamana's Otomeza Plug-in Tool
  3. *        スプライン曲線
  4. *    
  5. *    1995.08.20    2次関数を用いた補完
  6. *    1995.08.27    スプライン法に変更
  7. *    
  8. *    問題点
  9. *    ・汚いソースである(^^;)
  10. *    
  11. */
  12. #include    "otome_pi.h"
  13.  
  14. const char longname[] = "DRAW  : スプライン曲線";
  15. int            cnfg_max = 1;
  16. PI_CNFG        cnfg[] = {
  17.                 {"線の太さ"        , 1, 32,  1,  1 }
  18.             };
  19.  
  20. #define    USE_ENV        PI_SET_ENV
  21. #define    USE_TYPE    PI_EFFC_POLY
  22. #include    "otome_pi.c"
  23.  
  24. typedef struct
  25.     {
  26.         short    x,y;
  27.         
  28.     }Points;
  29.  
  30. /*******************************************************/
  31.  
  32. int num;
  33.  
  34. int mk_spTbl( x,y,f )
  35. double    *x,*f;
  36. int     *y;
  37. {
  38.     int     i;
  39.     double    t,*h,*d;
  40.     
  41.     if( (h=(double *)PI_MALLOC( sizeof(double)*num*2 ))==NULL )
  42.         return ERROR;
  43.     d = &h[ num ];
  44.     
  45.     f[0] = f[num-1] = 0;
  46.     for( i=0; i<num-1; i++ )
  47.     {
  48.         h[i  ] = (x[i+1] - x[i]);
  49.         d[i+1] = (y[i+1] - y[i]) / h[i];
  50.     }
  51.     
  52.     f[1] =  d[2] - d[1];
  53.     d[1] = (x[2] - x[0])*2 ;
  54.     for( i=1; i<num-2; i++ )
  55.     {
  56.         t = (h[i] / d[i]);
  57.         f[i+1] = (d[i+2] - d[i+1])   - f[i] * t;
  58.         d[i+1] = (x[i+2] - x[i  ])*2 - h[i] * t;
  59.     }
  60.     f[num-2] -= h[num-2]*f[num-1];
  61.     for( i=num-2; i>0; i-- )
  62.         f[i] = (f[i] - h[i] * f[i+1]) / d[i];
  63.     
  64.     return NOERR;
  65. }
  66.  
  67. int     get_sp( t,x,y,f )
  68. double    *x,*f;
  69. int     t,*y;
  70. {
  71.     int     i,j,k;
  72.     int     d,h;
  73.     
  74.     i=0,j=num-1;
  75.     while( i<j )
  76.     {    k = (i+j)/2;
  77.         if( x[k] < t )    i = k+1;
  78.                 else    j = k;
  79.     }
  80.     if( i>0 )    i--;
  81.     
  82.     h = (x[i+1] - x[i]);
  83.     d = (   t   - x[i]);
  84.     
  85.     return (
  86.               ((f[i+1] - f[i])* d * 256 / h +  f[i] * 3 *256 ) * d
  87.             + ((y[i+1] - y[i])    * 256 / h - (f[i] * 2 + f[i+1])* h*256 )
  88.         ) * d /256 + y[i];
  89.     
  90. }
  91.  
  92. int spline( pp )
  93. Points    *pp;
  94. {
  95.     int     i;
  96.     int     x0,y0,x1,y1,step;
  97.     int     t0,t1,*x,*y;
  98.     double    *l,*a,*b;
  99.     
  100.     LINE    line;
  101.     line.n = 2;
  102.     
  103.     /* double=64bit,int=32bit */
  104.     if( (l=(double *)PI_MALLOC( sizeof(double)*num*4 ))==NULL )
  105.         return PI_ERROR_NO_MEMORY;
  106.     a = &l[num];
  107.     b = &a[num];
  108.     x = (int*)&b[num];
  109.     y = (int*)&x[num];
  110.     
  111.     for( i=0; i<num ; i++)
  112.     {    x[i] = pp[i].x;
  113.         y[i] = pp[i].y;
  114.     }
  115.     l[0] = 0;
  116.     for( i=1; i<num; i++ )    /* 始点からの総距離 */
  117.     {    t0 = x[i] - x[i-1];
  118.         t1 = y[i] - y[i-1];
  119.         l[i] = l[i-1] + (int)sqrt( t0*t0 + t1*t1 );
  120.     }
  121.     mk_spTbl( l, x, a );
  122.     mk_spTbl( l, y, b );
  123.     
  124.     /* 速度と精度のバランスをうまく取りたい(^^;) */
  125.     step = l[num-1]/128;
  126.     for( i=256; (t0=l[num-1]/i)>0 ; i*=2 )
  127.         step -= t0;
  128.     if( step <= 0 )    step  = 2;
  129.             else    step *= 2;
  130.     
  131.     x0 = get_sp( 0, l, x, a );
  132.     y0 = get_sp( 0, l, y, b );
  133.     
  134.     for( i=1 ; i<=l[num-1] ; i+=step )
  135.     {    x1 = get_sp( i, l, x, a );
  136.         y1 = get_sp( i, l, y, b );
  137.         
  138.         line.x0 = x0;
  139.         line.y0 = y0;
  140.         line.x1 = x1;
  141.         line.y1 = y1;
  142.         EGB_connect( EgbPtr, &line );
  143.         
  144.         x0=x1,y0=y1;
  145.     }
  146.     if( i-step < l[num-1] )
  147.     {    i = l[num-1];
  148.         x1 = get_sp( i, l, x, a );
  149.         y1 = get_sp( i, l, y, b );
  150.         
  151.         line.x0 = x0;
  152.         line.y0 = y0;
  153.         line.x1 = x1;
  154.         line.y1 = y1;
  155.         EGB_connect( EgbPtr, &line );
  156.     }
  157. sp_end:
  158.     PI_FREE( l );
  159.     
  160.     return NOERR;
  161. }
  162.  
  163.  
  164. /*************************************/
  165.  
  166. int APL_exec()
  167. {
  168.     int     pen;
  169.     
  170.     pen  = cnfg[0].val;
  171.     
  172.     EGB_writePage( EgbPtr, PI_PAGE );
  173.     EGB_writeMode( EgbPtr, EGB_PSET );
  174.     
  175.     /* タイル指定を有効に */
  176.     if( PI_TILEFLG )
  177.     {    EGB_tilePattern( EgbPtr, EGB_FORECOL,
  178.                     PI_TILE_X, PI_TILE_Y, PI_TILE_PAT );
  179.         EGB_paintMode( EgbPtr, EGB_PAINT_TILE );
  180.     }else
  181.     {    EGB_color( EgbPtr, EGB_FORECOL,  PI_FORECOL );
  182.         EGB_paintMode( EgbPtr, EGB_PAINT_BETA );
  183.     }
  184.     EGB_penSize( EgbPtr, pen );
  185.     
  186.     /****/
  187.     
  188.     num = WORD( g_para );
  189.     return spline( (Points *)(g_para+2) );
  190.     
  191. }
  192.  
  193.